{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "CP4Mg2LwZ0ee"
   },
   "source": [
    "##### Copyright 2020 The Cirq Developers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "cellView": "form",
    "id": "OgHgJkWtZ08Q"
   },
   "outputs": [],
   "source": [
    "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
    "# you may not use this file except in compliance with the License.\n",
    "# You may obtain a copy of the License at\n",
    "#\n",
    "# https://www.apache.org/licenses/LICENSE-2.0\n",
    "#\n",
    "# Unless required by applicable law or agreed to in writing, software\n",
    "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
    "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "# See the License for the specific language governing permissions and\n",
    "# limitations under the License."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "nrqc5AdQWHND"
   },
   "source": [
    "# Google Quantum Computing Service"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "OQdp_uLYZz8l"
   },
   "source": [
    "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://www.example.org/cirq/google/concepts\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on QuantumLib</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/quantumlib/Cirq/blob/master/docs/google/concepts.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://github.com/quantumlib/Cirq/blob/master/docs/google/concepts.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a href=\"https://storage.googleapis.com/tensorflow_docs/Cirq/docs/google/concepts.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Download notebook</a>\n",
    "  </td>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "bd9529db1c0b"
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    import cirq\n",
    "except ImportError:\n",
    "    print(\"installing cirq...\")\n",
    "    !pip install --quiet cirq\n",
    "    print(\"installed cirq.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "EkFikKuDV3D1"
   },
   "source": [
    "*Run quantum computing programs on Google’s quantum processors*\n",
    "\n",
    "Quantum Computing Service gives customers access to Google's quantum computing hardware.  Programs that are written in Cirq, an open-source quantum computing program language, can be sent to run on a quantum computer in Google’s quantum computing lab in Santa Barbara, CA. You will be able to do  arbitrary single qubit rotations as well as several choices of two qubit gates.  Measurements of all qubits as a final step are also supported. \n",
    "\n",
    "Access is currently only granted to those on an approved list.  Apply to become an early access partner with this [questionnaire](https://docs.google.com/forms/d/1DfUWu4zUAJ87GKy-ZoTHrFri5IwIteKtMxKfsy3lmHE).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4gv7nr20bVNu"
   },
   "source": [
    "## Concepts\n",
    "\n",
    "Quantum Computing Service uses Cirq, an open source Python framework for creating quantum programs and running them against simulators or against real quantum computers.    Here we provide a conceptual overview of how to run a quantum program on a quantum processor.\n",
    "\n",
    "Installing Cirq:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "9A-6IYPeb6_g"
   },
   "source": [
    "### Circuits\n",
    "\n",
    "The language of quantum computing is the quantum circuit model.  Cirq is our open source framework which allows one to write a quantum circuit model in Python.  To learn more about Cirq itself, we recommend starting with the [Tutorial](../tutorials/basics.ipynb).  Conceptually Cirq can be thought of as a way to create an object in Python that contains the information about a quantum circuit.  Here, for example, we create a single circuit made up of square root of NOT gates, controlled-Z gates, and a measurement:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "E2VjfwVubc8V"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0: ───X^0.5───@────────────────\n",
      "              │\n",
      "1: ───X^0.5───@───@────────────\n",
      "                  │\n",
      "2: ───X^0.5───────@───M('m')───\n"
     ]
    }
   ],
   "source": [
    "import cirq\n",
    "\n",
    "q0, q1, q2 = cirq.LineQubit.range(3)\n",
    "circuit = cirq.Circuit(\n",
    "    (cirq.X ** 0.5).on_each(q0, q1, q2),\n",
    "    cirq.CZ(q0, q1),\n",
    "    cirq.CZ(q1, q2),\n",
    "    cirq.measure(q2, key='m')\n",
    ")\n",
    "print(circuit)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "P-_8Gl-HZTZH"
   },
   "source": [
    "### Quantum Engine API\n",
    "\n",
    "Quantum Engine is the name of the cloud API which one can call to run the circuits you create in Cirq on simulator or on quantum computers.  When access is enabled, users can write code in Cirq that makes a call to Google’s servers to run a circuit that they have built in Cirq on simulators or on quantum computers.  Read more about how to do this using cirq's `Engine` class [here](./engine.ipynb).\n",
    "\n",
    "![Quantum Engine Conceptual Diagram](../images/engine_diagram.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "zxWBUwkfZVBI"
   },
   "source": [
    "### Quantum Programs\n",
    "\n",
    "In Cirq, one creates a `Circuit` in Python.  If one then wants to run it using Quantum Engine, one must then upload this Circuit (or Schedule) to the Quantum Engine.  The uploaded version of the Circuit/Schedule is called a Program.  Programs are not the Python code itself, but a representation of the Circuit in a hardware specific language.  Though you will need to make sure that your circuit uses only gates and qubits compatible with the hardware (see `cirq.google.optimized_for_sycamore()` to help with this), the `Engine` class and its corresponding `sampler` will translate the circuit to this serialized form for you.\n",
    "\n",
    "![Quantum Program Conceptual Diagram](../images/engine_program.png)\n",
    "\n",
    "When you upload a program to Quantum Engine, the program is given a name.  The organizational unit of Quantum Engine is the cloud project (see below), so when you create a program it is identified by the project id and the program id.  We write this as a path\n",
    "\n",
    "```\n",
    "<PROJECT_ID>/programs/<PROGRAM_ID>\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0lv_Baq4ZYpO"
   },
   "source": [
    "### Cloud Project\n",
    "\n",
    "Quantum Engine interfaces with Google Cloud.  In Google Cloud one can create different projects with different names.  For instance, you might create a project that is for your experiments on quantum computers, and you might create one to manage your side business running servers that day trade Star Wars memorabilia.  Everything under your cloud project can be seen by navigating to the Google Cloud console.  Here, for example, we see the programs that have been uploaded to a quantum projected called “Quantum Cloud Client”:\n",
    "\n",
    "![Quantum Cloud Conceptual Diagram](../images/engine_cloud.png)\n",
    "\n",
    "See the [Getting Started](../tutorials/google/start.ipynb) guide for step-by-step instructions on how to create a project and enable the API."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "gqrO-LvBZbbp"
   },
   "source": [
    "### Jobs\n",
    "\n",
    "Once a circuit has been uploaded as a program to Quantum Engine, you can run this program by creating a job.  When you create a job on Quantum Engine, the quantum engine then is responsible for routing your program and the information about the job to the appropriate simulator or quantum computer.  Note that there is a time limit for job length, so you will want to separate your programs into multiple jobs below this limit.\n",
    "\n",
    "![Quantum Jobs Conceptual Diagram](../images/engine_job.png)\n",
    "\n",
    "Quantum Engine is designed so that you can upload a program once and then, if that program has different parameters (see below), you can run this program multiple times by creating multiple jobs for a given program.  Jobs are associated with programs, so they have names which include everything about your program, plus a job id:\n",
    "\n",
    "```\n",
    "<project id>/programs/<program id>/jobs/<job id>  \n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "w2N-aTOgZgIe"
   },
   "source": [
    "### Parameterized Circuits and Job Context\n",
    "\n",
    "Circuits in Cirq can have quantum gates that are “parameterized”.  For example, a gate may represent a rotation of a qubit about the Z axis of the bloch sphere by an angle theta.  For parameterized circuit this angle theta is just specified by a variable, say “my-theta”.  In order to run such a circuit you will need to be able to tell the circuit what value of “my-theta” should be supplied.  In fact you can create a job for a program with parameterized gates which says run this for multiple parameter values.  Or each time you create a new job, you can specify new parameter values.  These parameter values are supplied in a “job context\"."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "wrQvQ4hvZio-"
   },
   "source": [
    "### Results\n",
    "\n",
    "Once a job has been scheduled to run on a machine (simulator or quantum computer), the machine returns the results of the program to the Quantum Engine.  The Quantum Engine stores these results.  Users can then query for these results (typically one pulls every fraction of a second):\n",
    "\n",
    "![Quantum Results Conceptual Diagram](../images/engine_result.png)\n",
    "\n",
    "There is only one result for one job, so results can be identified via the identity of the job followed by result:\n",
    "\n",
    "```\n",
    "<project id>/programs/<program id>/jobs/<job id>/result\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A2rh2gYzZkFf"
   },
   "source": [
    "### Processors\n",
    "\n",
    "When creating a job to run a program, one must specify where the job should run.  This can be a very specific machine to run on, or it can be specified more generally.  Each location that we can schedule a job to run on is described as a processor.  Different processors are available to different users, so processors appear under a project and have a processor id.\n",
    "\n",
    "```\n",
    "<project id>/processors/<processor id>\n",
    "```\n",
    "\n",
    "For example, one processor is the “rainbow” processor, which corresponds to a quantum computer located in Santa Barbara.  Another processor is “xmonsim” which is a fleet of simulators for the xmon architecture which all run in Google’s production datacenters.\n",
    "\n",
    "Processor have state associated with them.  For instance, a processor can be “online” or they can be in “maintenance” mode."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "nghWy0ALZnOL"
   },
   "source": [
    "### Calibration Metrics\n",
    "\n",
    "Processors that are quantum computers periodically undergo calibrations to maintain the quality of the programs that can be run on these processors.  During this calibration metrics about the performance of the quantum computer is collected.  This calibration data is stored by Quantum Engine and users can then query for the state of the calibration (one can ask for the latest calibration, or what the state of calibration was at a given point in time).  Calibrations are also available for past jobs.\n",
    "\n",
    "Calibration metrics and can be retrieved via the console or via cirq calls.  See more details on the [Calibration Metrics](calibration.ipynb) page."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "DiHuFRL-c9SP"
   },
   "source": [
    "### Reservations\n",
    "\n",
    "Processor schedules are managed by a reservation system, assigning blocks of time as \"time slots\" with four possible states:\n",
    "\n",
    "*  OPEN_SWIM: Anyone with processor access may run jobs.  There may be additional restrictions per processor that restrict large jobs.\n",
    "*  MAINTENANCE: restrictions behave the same as during open swim, but there are no guarantees about the availability of the processor or quality of jobs run during this period.\n",
    "*  RESERVATION: The processor is reserved for restricted use by a user or set of users. Reservations are rooted under a project and editors of that project may run jobs during that project's reservations while using any project they wish. Additional users may also be whitelisted to specific reservations.\n",
    "*  UNALLOCATED: The processor has not been scheduled for any purpose. A reservation may be made during this time. If nothing is scheduled during this block, it will default to behaving as open swim.\n",
    "\n",
    "During non-reservation times, jobs are restricted to run for at most 5 minutes and may have no more than 1,500,000 total shots on the processor.\n",
    "\n",
    "The schedule of a processor is \"frozen\" for 4 hours into the immediate future so that users can rely on it for the coming day.\n",
    "\n",
    "The ability to make reservations is restricted by budgets that are delegated by Quantum Computing Service admins. These are provided on a weekly basis and communicated either during the weekly user sync or by email and are good for one week in the future, but this policy is subject to change.\n",
    "\n",
    "You can use this [reservation colab utility](../tutorials/google/reservations.ipynb)  to view the processor schedule and make reservations."
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "concepts.ipynb",
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
